package com.payment.transactions.service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.payment.transactions.enums.IncomeExpenseType;
import com.payment.transactions.enums.PaymentPlatform;
import com.payment.transactions.model.PaymentTransaction;

@Service
public class FileImportService {
    // 文件格式常量
    private static final String XLSX = "xlsx";
    private static final String XLS = "xls";
    private static final String CSV = "csv";
    // 日期格式化（适配两种账单的时间格式）
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    // 支付平台枚举：1=微信，2=支付宝（与PaymentTransaction模型匹配）
    private static final Integer PLATFORM_WECHAT = 1;
    private static final Integer PLATFORM_ALIPAY = 2;
    // 收支类型枚举：0=收入，1=支出（与PaymentTransaction模型匹配）
    private static final Integer INCOME = 0;
    private static final Integer EXPENSE = 1;

    /**
     * 入口方法：根据文件名判断账单类型，调用对应解析逻辑
     */
    public List<PaymentTransaction> parseFile(MultipartFile file) throws IOException, ParseException {
        String fileName = file.getOriginalFilename();
        if (fileName == null || fileName.trim().isEmpty()) {
            throw new IllegalArgumentException("文件名不能为空");
        }
        String fileExtension = getFileExtension(fileName);

        // 1. 判断是否为微信账单（Excel格式，文件名含"微信支付"）
        if ((XLSX.equals(fileExtension.toLowerCase()) || XLS.equals(fileExtension.toLowerCase()))
                && fileName.contains("微信支付")) {
            return parseWeChatExcel(file.getInputStream(), fileExtension);
        }
        // 2. 判断是否为支付宝账单（CSV格式，文件名含"支付宝"）
        else if (CSV.equals(fileExtension.toLowerCase()) && fileName.contains("支付宝")) {
            return parseAlipayCsv(file.getInputStream());
        }
        // 3. 不支持的文件类型
        else {
            throw new IllegalArgumentException("不支持的文件格式或文件类型不匹配：" + fileName);
        }
    }

    /**
     * 解析微信支付Excel账单（适配文档3的列结构）
     * Excel列顺序：交易时间(0)、交易类型(1)、交易对方(2)、商品(3)、收/支(4)、金额(元)(5)、支付方式(6)、当前状态(7)、交易单号(8)、商户单号(9)、备注(10)
     */
    private List<PaymentTransaction> parseWeChatExcel(InputStream inputStream, String extension)
            throws IOException, ParseException {
        List<PaymentTransaction> transactions = new ArrayList<>();

        try (Workbook workbook = XLSX.equals(extension) ? new XSSFWorkbook(inputStream)
                : new HSSFWorkbook(inputStream)) {
            Sheet sheet = workbook.getSheetAt(0);
            if (sheet == null) {
                throw new IOException("微信账单Excel无工作表数据");
            }

            // 关键：跳过前15行非数据行（文档3中"微信支付账单明细列表"表头在第15行，数据从第16行开始）
            int dataStartRow = 17;
            for (int rowNum = dataStartRow; rowNum <= sheet.getLastRowNum(); rowNum++) {
                Row row = sheet.getRow(rowNum);
                if (row == null)
                    continue;

                // 验证行数据有效性（至少11列，匹配微信账单列数）
                if (row.getLastCellNum() < 11) {
                    continue;
                }

                PaymentTransaction transaction = new PaymentTransaction();
                // 1. 支付平台：固定为微信（1）
                transaction.setPaymentPlatform(PaymentPlatform.WECHAT.getCode());
                // 2. 交易时间（第0列）
                transaction.setTransactionTime(getCellValueAsDate(row.getCell(0)));
                // 3. 交易分类（第1列：微信账单的"交易类型"对应模型的"交易分类"）
                transaction.setTransactionCategory(getCellValueAsString(row.getCell(1)));
                // 4. 交易对方（第2列）
                transaction.setTransactionPartner(getCellValueAsString(row.getCell(2)));
                // 5. 对方账号（微信账单无明确"对方账号"，填充为空或备注信息）
                transaction.setPartnerAccount("");
                // 6. 商品说明（第3列：微信账单的"商品"对应模型的"商品说明"）
                transaction.setProductDescription(getCellValueAsString(row.getCell(3)));
                // 7. 收支类型（第4列："收入"/"支出"转换为枚举0/1）
                String incomeExpenseStr = getCellValueAsString(row.getCell(4));
                transaction.setIncomeExpense(IncomeExpenseType.fromDescription(incomeExpenseStr));
                // 8. 金额（第5列：清洗¥符号，转换为BigDecimal）
                String amountStr = getCellValueAsString(row.getCell(5)).replace("¥", "").trim();
                transaction.setAmount(parseBigDecimal(amountStr));
                // 9. 收/付款方式（第6列）
                transaction.setPaymentMethod(getCellValueAsString(row.getCell(6)));
                // 10. 交易状态（第7列：微信账单的"当前状态"对应模型的"交易状态"）
                transaction.setTransactionStatus(getCellValueAsString(row.getCell(7)));
                // 11. 交易订单号（第8列）
                transaction.setTransactionOrderNumber(getCellValueAsString(row.getCell(8)));
                // 12. 商家订单号（第9列：无则为空）
                transaction.setMerchantOrderNumber(getCellValueAsString(row.getCell(9)).replace("/", "").trim());
                // 13. 备注（第10列：无则为空）
                transaction.setRemarks(getCellValueAsString(row.getCell(10)).replace("/", "").trim());
                // 14. 默认值：未删除、创建/更新时间为当前时间
                transaction.setIsDeleted(0);
                Date now = new Date();
                transaction.setCreatedTime(now);
                transaction.setUpdatedTime(now);

                transactions.add(transaction);
            }
        }
        return transactions;
    }

    /**
     * 解析支付宝支付CSV账单（适配文档4的列结构）
     * CSV列顺序：交易时间(0)、交易分类(1)、交易对方(2)、对方账号(3)、商品说明(4)、收/支(5)、金额(6)、收/付款方式(7)、交易状态(8)、交易订单号(9)、商家订单号(10)、备注(11)
     */
    private List<PaymentTransaction> parseAlipayCsv(InputStream inputStream) throws IOException, ParseException {
        List<PaymentTransaction> transactions = new ArrayList<>();

        // 用BufferedReader读取CSV，指定GB2312编码（支付宝账单默认编码）
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "GB2312"))) {
            String line;
            int lineNum = 0;
            // 关键：跳过前25行非数据行（文档4中交易数据从第26行开始，前25行为导出信息、特别提示等）
            while ((line = reader.readLine()) != null) {
                lineNum++;
                System.out.println("Read line: " + lineNum + " " + line);
                // 跳过非数据行
                if (lineNum <= 25) {
                    continue;
                }

                // 分割CSV（处理逗号转义，适配标准CSV格式）
                String[] values = line.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");
                // 打印当前行数据（调试用）
                System.out.println("Processing line " + lineNum + ": " + Arrays.toString(values));

                PaymentTransaction transaction = new PaymentTransaction();
                // 1. 支付平台：固定为支付宝（2）
                transaction.setPaymentPlatform(PaymentPlatform.ALIPAY.getCode());
                // 2. 交易时间（第0列：处理可能的空值）
                transaction.setTransactionTime(parseDate(values[0].trim()));
                // 3. 交易分类（第1列）
                transaction.setTransactionCategory(values[1].trim());
                // 4. 交易对方（第2列）
                transaction.setTransactionPartner(values[2].trim());
                // 5. 对方账号（第3列：支付宝账号可能脱敏，直接保留）
                transaction.setPartnerAccount(values[3].trim());
                // 6. 商品说明（第4列）
                transaction.setProductDescription(values[4].trim());
                // 7. 收支类型（第5列："收入"/"支出"转换为枚举0/1）
                String incomeExpenseStr = values[5].trim();
                transaction.setIncomeExpense(IncomeExpenseType.fromDescription(incomeExpenseStr));
                // 8. 金额（第6列：直接转换为BigDecimal）
                transaction.setAmount(parseBigDecimal(values[6].trim()));
                // 9. 收/付款方式（第7列）
                transaction.setPaymentMethod(values[7].trim());
                // 10. 交易状态（第8列）
                transaction.setTransactionStatus(values[8].trim());
                // 11. 交易订单号（第9列：处理可能的制表符或空格）
                transaction.setTransactionOrderNumber(values[9].trim().replace("\t", ""));
                // 12. 商家订单号（第10列：处理可能的制表符或空格）
                transaction.setMerchantOrderNumber(values[10].trim().replace("\t", ""));
                // 13. 备注（第11列：无则为空）
                if (values.length > 11) {
                    transaction.setRemarks(values[11].trim());
                } else {
                    transaction.setRemarks("");
                }
                // 14. 默认值：未删除、创建/更新时间为当前时间
                transaction.setIsDeleted(0);
                Date now = new Date();
                transaction.setCreatedTime(now);
                transaction.setUpdatedTime(now);

                transactions.add(transaction);
            }
        }
        return transactions;
    }

    /**
     * 工具方法：获取文件扩展名
     */
    private String getFileExtension(String fileName) {
        int lastDotIndex = fileName.lastIndexOf('.');
        return lastDotIndex == -1 ? "" : fileName.substring(lastDotIndex + 1);
    }

    /**
     * Excel单元格工具：获取字符串值
     */
    private String getCellValueAsString(Cell cell) {
        if (cell == null)
            return "";
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue().trim();
            case NUMERIC:
                // 处理日期格式的数字单元格
                if (DateUtil.isCellDateFormatted(cell)) {
                    return DATE_FORMAT.format(cell.getDateCellValue());
                }
                // 处理普通数字（避免科学计数法）
                return String.valueOf(cell.getNumericCellValue()).replace(".0", "").trim();
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                // 公式单元格取计算结果
                try {
                    return new DataFormatter().formatCellValue(cell);
                } catch (Exception e) {
                    return cell.getCellFormula();
                }
            default:
                return "";
        }
    }

    /**
     * Excel单元格工具：获取日期值
     */
    private Date getCellValueAsDate(Cell cell) throws ParseException {
        if (cell == null)
            return null;
        String cellValue = getCellValueAsString(cell);
        return cellValue.isEmpty() ? null : DATE_FORMAT.parse(cellValue);
    }

    /**
     * 通用工具：解析BigDecimal（处理空值和格式错误）
     */
    private BigDecimal parseBigDecimal(String value) {
        if (value == null || value.trim().isEmpty()) {
            return BigDecimal.ZERO;
        }
        try {
            return new BigDecimal(value.trim());
        } catch (NumberFormatException e) {
            return BigDecimal.ZERO;
        }
    }

    /**
     * 通用工具：解析Date（处理空值）
     */
    private Date parseDate(String value) throws ParseException {
        if (value == null || value.trim().isEmpty()) {
            return null;
        }
        return DATE_FORMAT.parse(value.trim());
    }
}